#pragma once
#include "Connection.hpp"
#include <iostream>
#include "Protocol.hpp"
#include <string>
#include "Calculate.hpp"

class HandlerConnection
{
public:
    static void HandlerRequest(Connection* conn)
    {
        std::string& bufferin = conn->BufferIn();
        std::string& bufferout = conn->BufferOut();
        while(true)
        {
            std::string request = DeCode(bufferin);
            if(request.empty()) break;
            std::shared_ptr<Request> req_ptr = Factory::BulidRequest();
            req_ptr->DeSerialize(request);
            std::shared_ptr<Response> resp_ptr = Calculate().Cal(req_ptr);
            std::string response = resp_ptr->Serialize();
            std::string package = EnCode(response);
            bufferout += package;
        }
        if(!bufferout.empty())
        {
            conn->_sender(conn);
        }
    }
    static void Recver(Connection* conn)        //static这样就不用bind自己，不然的话，智能指针一个对象出来用来bind
    {       //但是这样就不能访问非静态成员变量，那么就把HandlerRequest也static
        char buffer[1024];
        std::string& bufferin = conn->BufferIn();
        while(true)
        {
            errno = 0;
            int n = recv(conn->GetSockfd(), buffer, 1023, 0);   //这个造成errno
            if(n > 0)
            {
                buffer[n] = 0;
                bufferin += buffer;
            }
            // else if(n == 0)      //这里不能有，，n是=0，但是errno也是EAGAIN
            // {
            //     lg.LogMessage(Info, "client quit??\n");
            //     break;
            // }
            else
            {
                if(n == 0) lg.LogMessage(Info, "client quit??\n");
                if(errno == EAGAIN)
                {
                    lg.LogMessage(Info, "接收缓冲区已读完\n");
                    errno = 0;      //防止对别人的判断, 出现问题后马上置回0
                    break;
                }
                else if(errno == EINTR)
                {
                    lg.LogMessage(Warning, "recv被信号中断\n");
                    errno = 0;
                    continue;
                }
                else
                {
                    lg.LogMessage(Error, "读错误, errno:%d:%s\n", errno, strerror(errno));
                    errno = 0;
                    return conn->_excepter(conn);
                }
            }
        }
        HandlerRequest(conn);
    }
    static void Sender(Connection* conn)
    {
        std::string& bufferout = conn->BufferOut();     
        while(true)
        {
            errno = 0;  //send会出现errno
            int n = send(conn->GetSockfd(), bufferout.c_str(), sizeof bufferout - 1, 0);
            if(n >= 0)
            {
                bufferout.erase(0, n);            
                if(bufferout.empty()) return;    //只要不是空，就证明发送发送缓冲区满了
            }
            else
            {
                if(errno == EAGAIN)
                {
                    lg.LogMessage(Warning, "发送缓冲区满了\n");
                    break;
                }
                else if(errno == EINTR)
                    lg.LogMessage(Warning, "被信号中断");
                else
                    return conn->_excepter(conn);
            }
        }
        //走到这就一定是EAGAIN
        conn->_R->ReNewConnection(conn->GetSockfd(), EPOLLIN|EPOLLOUT|EPOLLET);
    }    
    static void Excepter(Connection* conn)
    {
        lg.LogMessage(Error, "connection error...\n");
        conn->_R->RemoveConnection(conn->GetSockfd());
        delete conn; //最后释放本身
    }
};